﻿
namespace MathService.DSP
{
    /// <summary>Цифровой фильтр нижних частот (RC-цепочка)</summary>
    public class DigitalLowPassRCFilter : CBIH
    {
        /// <summary>Получить коэффициенты полинома знаменателя передаточной функции цифрового фильтра</summary>
        ///<param name="f0">Частота среза</param>
        ///<param name="dt">Частота дискретизации</param>
        /// <returns>Коэффициенты полинома a0 + a1 z^-1</returns>
        private static double[] GetA(double f0, double dt)
        {
            var tau2 = 2 / f0;
            return new[] { 1, (dt - tau2) / (dt + tau2) };
        }

        /// <summary>Получить коэффициенты полинома числителя передаточной функции цифрового фильтра</summary>
        ///<param name="f0">Частота среза</param>
        ///<param name="dt">Частота дискретизации</param>
        /// <returns>Коэффициенты полинома b0 + b1 z^-1</returns>
        private static double[] GetB(double f0, double dt)
        {
            var b = f0 * dt;
            b /= (b + 2);
            return new[] { b, b };
        }

        /// <summary>Частота среза</summary>
        private double f_f0;
        /// <summary>Период дискретизации</summary>
        private double f_dt;

        /// <summary>Частота среза</summary>
        public double f0 { get { return f_f0; } set { if(value != f_f0) Initialize(value, f_dt); } }
        /// <summary>Период дискретизации</summary>
        public double dt { get { return f_dt; } set { if(value != f_dt) Initialize(f_f0, value); } }

        ///<summary>Цифровой фильтр нижних частот (RC-цепочка)</summary>
        ///<param name="f0">Частота среза</param>
        ///<param name="dt">Частота дискретизации</param>
        public DigitalLowPassRCFilter(double f0, double dt)
            : base(GetA(f0, dt), GetB(f0, dt))
        {
            f_f0 = f0;
            f_dt = dt;
        }

        ///<summary>Инициализация фильтра</summary>
        ///<param name="f0">Частота среза</param>
        ///<param name="dt">Частота дискретизации</param>
        public void Initialize(double f0, double dt) { Initialize(GetA(f_f0 = f0, f_dt = dt), GetB(f0, dt)); }
    }
}
